package com.shopping_back.serviceImpl;

import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shopping_back.exception.BizException;
import com.shopping_back.mapper.*;
import com.shopping_back.pojo.vo.GroupDetailVO;
import com.shopping_back.pojo.dto.JoinGroupDTO;
import com.shopping_back.pojo.dto.OpenGroupDTO;
import com.shopping_back.pojo.dto.PageDTO;
import com.shopping_back.pojo.entity.*;
import com.shopping_back.pojo.vo.GroupCardVO;
import com.shopping_back.pojo.vo.GroupbuyDetailVO;
import com.shopping_back.service.IGroupbuyService;
import com.shopping_back.service.IOrderMainService;
import com.shopping_back.service.IPayService;
import com.shopping_back.util.InviteCodeUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class GroupbuyServiceImpl implements IGroupbuyService {

    private final GroupbuyGroupMapper groupMapper;
    private final GroupbuyMemberMapper memberMapper;
    private final GroupbuyItemMapper   itemMapper;
    private final PromotionActivityMapper promotionMapper;
    private final SkuMapper skuMapper;
    private final SpuMapper spuMapper;
    private final OrderMainMapper orderMainMapper;
    private  final IOrderMainService orderService;
    private  final IPayService payService;

    /* ------------------ 开团 ------------------ */
    @Transactional
    public Map<String,Object> openGroup(OpenGroupDTO dto, Long userId) {

        // 校验活动
        GroupbuyItem rule = itemMapper.selectById(dto.getSkuId());
        if (rule == null) {
            throw new IllegalArgumentException("拼团规则未启用或已过期");
        }
        PromotionActivity promotion = promotionMapper.selectById(rule.getActivityId());
        if (promotion == null
                || promotion.getStartTime().isAfter(LocalDateTime.now())
                || promotion.getEndTime().isBefore(LocalDateTime.now())) {
            throw new IllegalArgumentException("没有该活动");
        }


        Integer requireCnt  = rule.getRequiredCount();
        BigDecimal price    = rule.getGroupPrice();
        long durationMins   = rule.getDurationMinutes();


        String inviteCode;
        do {
            inviteCode = InviteCodeUtil.generate(6);      // 6 位大写字母+数字
        } while (groupMapper.existsByInviteCode(inviteCode));

        // 创建 group
        GroupbuyGroup g = new GroupbuyGroup();
        g.setItemSkuId(rule.getSkuId());
        g.setInviteCode(inviteCode);
        g.setLeaderUserId(userId);
        g.setJoinedCount(1);
        g.setExpireTime(LocalDateTime.now()
                .plusMinutes(rule.getDurationMinutes()));
        g.setStatus(0);
        groupMapper.insert(g);

        /* ③ 下单：订单 status = -1 */
        Sku sku = skuMapper.selectById(rule.getSkuId());
        Spu spu = spuMapper.selectById(sku.getSpuId());

        OrderMain order = orderService.createPaidGroupOrder(
                userId, g.getId(), sku, spu,
                dto.getQuantity(), rule.getGroupPrice());      // status -1

        /* ④ 写 leader 成员 */
        GroupbuyMember leader = new GroupbuyMember();
        leader.setGroupId(g.getId());
        leader.setUserId(userId);
        leader.setQuantity(dto.getQuantity());
        leader.setOrderId(order.getId());
        leader.setStatus(0);
        memberMapper.insert(leader);

        return Map.of(
                "groupId",    g.getId(),
                "inviteCode", inviteCode,
                "orderSn",    order.getOrderSn()          // 方便前端展示 / 查询
        );
    }


    /* ------------------ 参团 ------------------ */
    @Transactional
    @Override
    public Map<String, Object> joinGroupByCode(JoinGroupDTO dto, Long userId) {

        /* ---------- 1. 校验拼团 ---------- */
        GroupbuyGroup g = groupMapper.findByInviteCode(dto.getInviteCode());
        if (g == null || g.getStatus() != 0)
            throw new IllegalArgumentException("拼团不存在或已结束");
        if (g.getExpireTime().isBefore(LocalDateTime.now()))
            throw new IllegalArgumentException("拼团已超时");
        if (memberMapper.existsByGroupIdAndUserId(g.getId(), userId))
            throw new IllegalArgumentException("已参团");

        /* ② 创建“已付待成团”订单 (status = -1) */
        GroupbuyItem rule = itemMapper.selectById(g.getItemSkuId());
        Sku sku = skuMapper.selectById(rule.getSkuId());
        Spu spu = spuMapper.selectById(sku.getSpuId());

        OrderMain order = orderService.createPaidGroupOrder(
                userId, g.getId(), sku, spu,
                dto.getQuantity(), rule.getGroupPrice());      // status -1

        /* ③ 写成员表 */
        GroupbuyMember m = new GroupbuyMember();
        m.setGroupId(g.getId());
        m.setUserId(userId);
        m.setQuantity(dto.getQuantity());
        m.setOrderId(order.getId());
        m.setStatus(0);
        memberMapper.insert(m);

        /* ④ 更新人数 & 判定是否成团 */
        g.setJoinedCount(g.getJoinedCount() + 1);

        if (g.getJoinedCount() >= rule.getRequiredCount()) {
            /* —— 拼团成功 —— */
            g.setStatus(1);
            groupMapper.updateById(g);
            memberMapper.updateStatusByGroupId(g.getId(), 1);

            /* 批量把所有订单 1 ➜ 2（待发货） */
            List<Long> orderIds = memberMapper.selectOrderIdsByGroupId(g.getId());
            if (!orderIds.isEmpty()) {
                orderMainMapper.update(
                        null,
                        new LambdaUpdateWrapper<OrderMain>()
                                .in(OrderMain::getId, orderIds)
                                .set(OrderMain::getStatus, 2)
                );
            }
            // TODO: 通知发货
        } else {
            groupMapper.updateById(g);            // 继续拼团
        }

        return Map.of(
                "groupId", g.getId(),
                "orderSn", order.getOrderSn()
        );
    }

    @Scheduled(cron = "0 */5 * * * ?")
    @Transactional
    public void autoRefundFailedGroups() {

        List<GroupbuyGroup> overdue = groupMapper.selectList(
                Wrappers.<GroupbuyGroup>lambdaQuery()
                        .eq(GroupbuyGroup::getStatus, 0)
                        .lt(GroupbuyGroup::getExpireTime, LocalDateTime.now()));

        for (GroupbuyGroup g : overdue) {

            g.setStatus(2);                               // 标记失败
            groupMapper.updateById(g);
            memberMapper.updateStatusByGroupId(g.getId(), 2);

            List<Long> orderIds = memberMapper.selectOrderIdsByGroupId(g.getId());
            for (Long oid : orderIds) {
                // ===== TODO: 实际退款逻辑 =====

                // refundService.refund(oid);
                orderService.refundOrder(oid);

                orderMainMapper.update(
                        null,
                        new LambdaUpdateWrapper<OrderMain>()
                                .eq(OrderMain::getId, oid)
                                .set(OrderMain::getStatus, 6)
                );
            }
            // TODO: 回滚库存

        }
    }


    /* ------------------ 团详情 ------------------ */
    @Override
    public GroupDetailVO getGroupDetail(Long groupId) {

        GroupbuyGroup g = groupMapper.selectById(groupId);
        if (g == null) {
            throw new IllegalArgumentException("团不存在");
        }

        List<GroupbuyMember> members = memberMapper.findByGroupId(groupId);

        GroupDetailVO vo = new GroupDetailVO();
        vo.setGroup(g);
        vo.setMembers(members);
        GroupbuyItem rule = itemMapper.selectById(g.getItemSkuId());
        vo.setJoinedCount(g.getJoinedCount());
        vo.setRequiredCount(rule.getRequiredCount());
        return vo;
    }

    @Override
    public List<GroupbuyDetailVO> getDetails(Long activityId) {
        List<GroupbuyDetailVO> list = itemMapper.selectDetails(activityId);
        System.out.println("团购信息"+list);
        if (list.isEmpty()) {
            throw new IllegalArgumentException("活动不存在或非团购");
        }
        return list;
    }

    @Override
    public GroupDetailVO getGroupDetailByCode(String inviteCode) {
        GroupbuyGroup g = groupMapper.findByInviteCode(inviteCode);

        if (g == null)
            throw new IllegalArgumentException("拼团不存在");

        List<GroupbuyMember> members = memberMapper.selectList(
                Wrappers.<GroupbuyMember>lambdaQuery()
                        .eq(GroupbuyMember::getGroupId, g.getId()));

        GroupDetailVO vo = new GroupDetailVO();
        vo.setGroup(g);
        vo.setMembers(members);
        GroupbuyItem rule = itemMapper.selectById(g.getItemSkuId());
        vo.setJoinedCount(g.getJoinedCount());
        vo.setRequiredCount(rule.getRequiredCount());
        return vo;
    }
}

